Podman - Premiers pas avec le conteneur sans racine
Podman en exécution sans racine
Premiers pas avec Podman sans racine
Assurez-vous d'avoir slirp4netnsinstallé
Assurez-vous que vos subuidet subgidsont correctement configurés
Vous voulez lier des ports inférieurs à 1024 ?
Podman est un produit Red Hat destiné à remplacer Docker. Pour 99% des tâches, il s'agit en effet d'un véritable remplaçant de Docker. Certaines de ses fonctionnalités sont la prise en charge des conteneurs sans racine , l'utilisation du modèle fork/exec pour démarrer les conteneurs, l' absence de démon , etc.
Les avantages d'un conteneur sans racine sont évidents. S'il peut être empêché de s'exécuter en tant que root, vous l'exécutez sans les privilèges root.
Si vous êtes un professionnel de l'informatique chevronné, vous avez peut-être commis l'un des crimes suivants :
•.Exécuter la dockercommande à l'aide de sudo, en augmentant ses privilèges
•.Ajout de votre utilisateur non root au dockergroupe. gros ouf
Comme vous l'avez peut-être déjà compris, il s'agit d'une pratique de sécurité terrible. Vous donnez au démon Docker un accès racine à votre machine. Cela expose deux méthodes d'exploitation :
•.Le démon Docker ( dockerd) s'exécute en tant que root. S'il dockerdprésente une faille de sécurité, l'ensemble de votre système est compromis car dockerdil s'agit d'un processus appartenant à l' rootutilisateur.
•.Une image que vous utilisez peut présenter des vulnérabilités. Que se passe-t-il si l'image vulnérable est utilisée par un conteneur qui s'exécute en tant que processus de l' rootutilisateur ? Un attaquant peut utiliser l'image vulnérable pour accéder à l'ensemble de votre système.
La solution est simple, n'exécutez pas tout en tant que root, même si vous lui faites confiance. N'oubliez pas que rien n'est sûr à 100 % . Je vous présente la capacité de Podman à gérer des conteneurs sans accès root.
Si vous démarrez un conteneur en utilisant Podman en tant qu'utilisateur non root, ledit conteneur n'obtient aucun privilège supplémentaire et Podman ne vous demandera pas non plus de mot de sudopasse.
Vous trouverez ci-dessous les avantages que Podman offre lorsque vous l'utilisez pour des conteneurs sans racine (sans aucun privilège de super-utilisateur) :
•.Vous pouvez isoler un groupe de conteneurs communs par utilisateur local. (par exemple, exécutez Nextcloud et MariaDB sous l'utilisateur nextcloud_useret les conteneurs Gitea et PostgreSQL sous l'utilisateur gitea_user)
•.Même si un conteneur/Podman est compromis, il ne peut pas obtenir un contrôle complet sur le système hôte, car l'utilisateur qui exécute le conteneur n'est pas root. Mais oui, l'utilisateur sous lequel s'exécute le conteneur exploité pourrait tout aussi bien être considéré comme un utilisateur devenu voyou .
Lorsque vous utilisez Podman/Docker root-full, vous accordez des privilèges de niveau super-utilisateur à Podman/Docker. C'est certainement très mauvais, mais cela signifie également que toutes les fonctionnalités annoncées fonctionnent comme prévu.
Au lieu de cela, lorsque vous exécutez des conteneurs Podman sans privilèges root, il a certaines limites. Certains des principaux sont les suivants :
•.Les images de conteneur ne peuvent pas être partagées entre les utilisateurs. Si user0 tire l'image ‘nginx:stable-alpine ', user1 devra tirer séparément l' image 'nginx:stable-alpine ' pour eux-mêmes. Il n'existe aucun moyen [du moins pas encore] qui vous permette de partager des images entre utilisateurs. Mais, vous pouvez copier des images d'un utilisateur à un autre utilisateur, reportez-vous à ce guide de Red Hat .
•.Les ports inférieurs à 1024 ne peuvent pas être liés par défaut . Une solution de contournement existe .
•.Un conteneur sans racine peut ne pas être en mesure d'envoyer un ping à tous les hôtes. Une solution de contournement existe .
•.Si vous spécifiez un UID dans un conteneur Podman sans racine, tout UID qui n'est pas mappé à un conteneur préexistant peut échouer. Il est préférable d'exécuter Podman à partir d'un shell utilisateur existant. Ou mieux encore, créez un service systemd pour le démarrer automatiquement .
Avant de vous lancer dans l'exécution sans racine des conteneurs, quelques conditions préalables doivent être remplies.
Le package slirp4netns est utilisé pour fournir une mise en réseau en mode utilisateur pour les espaces de noms de réseau non privilégiés. Ceci est nécessaire si vous voulez que votre conteneur sans racine interagisse avec n'importe quel type de réseau.
Vous pouvez installer le slirp4netnspaquet sur les distributions Linux basées sur Debian/Ubuntu en utilisant le aptgestionnaire de paquets comme ceci :
sudo apt install slirp4netns
Sur les distributions Linux basées sur Fedora/RHEL, utilisez le dnfgestionnaire de packages pour installer slirp4netnscomme suit :
sudo dnf install slirp4netns
Vous, les utilisateurs d'Arch Linux, savez comment le faire avec pacman, mais quoi qu'il en soit, voici la commande que vous recherchez peut-être :
sudo pacman -Sy slirp4netns
Étant donné que les conteneurs Podman sans racine sont exécutés par un utilisateur existant sur le système, lesdits utilisateurs non root ont besoin d'une autorisation pour exécuter un conteneur sans racine en tant qu'UID qui n'est pas leur propre UID. Ceci s'applique également au GID.
Chaque utilisateur reçoit une plage d'UID qu'il est autorisé à utiliser. Ceci est spécifié dans le fichier /etc/subuid ; et le fichier /etc/subgid est pour les GID qu'un utilisateur est autorisé à utiliser.
Le format de ce fichier est le suivant :
username:initial UID/GID allocated to user:range/size of allowd UIDs/GIDs
Donc, disons que mon utilisateur utlisateur1 veut UID 100 et utlisateur2 veut UID 1000 . Voici à quoi ressemblerait le fichier /etc/subuid:
utlisateur1:100000:100
utlisateur2:100100:1000
Cela signifie en fait que l'utilisateur utlisateur1 peut utiliser des UID entre '100000' et '100100'. Pendant ce temps, l'utilisateur utlisateur2peut utiliser des UID entre '100100' et '101100'.
Habituellement, cela est déjà configuré pour chaque utilisateur que vous créez. Et généralement, cette plage est définie sur '65536' GID/UID Mais dans certains cas, cela doit être fait manuellement.
Mais attendez, si ce n'est pas déjà fait pour votre utilisateur, vous n'avez pas besoin de le faire à la main pour chaque utilisateur. Vous pouvez utiliser la commande usermod pour cela. Voici la syntaxe de la commande pour le faire :
sudo usermod --add-subuids START-RANGE --add-subgids START-RANGE USERNAME
Remplacez START, RANGE et USERNAME selon vos besoins.
⚠️
Assurez-vous que les autorisations pour les fichiers /etc/subuidet /etc/subgid sont définies sur 644 et appartiennent à root:root.
Si vous utilisez un proxy inverse pour SSL, vous saurez que les ports 80 et 443 doivent être accessibles par un fournisseur de certificats comme Let's Encrypt .
Si vous essayez de lier des ports inférieurs à 1024 à un conteneur sans racine géré par Podman, vous remarquerez que ce n'est pas possible. Eh bien, c'est possible, mais ce n'est pas configuré par défaut .
Un utilisateur non root n'est pas autorisé à lier quoi que ce soit sur les ports inférieurs au port 1024.
Alors, comment lier les ports inférieurs à 1024 dans Podman sans racine ? Pour ce faire, déterminez d'abord le port le plus bas dont vous avez besoin. Dans mon cas, pour déployer SSL, j'ai besoin des ports 80 et 443. Le port le plus bas dont j'ai besoin est donc le port 80.
Une fois cela déterminé, ajoutez la ligne suivante au fichier /etc/sysctl.conf:
net.ipv4.ip_unprivileged_port_start=YOUR_PORT_NUMBER
Essentiellement, vous modifiez la valeur de net.ipv4.ip_unprivileged_port_start pour le port le plus bas dont vous avez besoin. Si je remplace YOUR_PORT_NUMBER par 80, je peux lier le port 80 à Podman dans un conteneur sans racine.
Comme je l'ai souligné plus tôt, une limitation de Podman est qu'il ne peut pas partager d'images entre les utilisateurs. Ils doivent soit être extraits pour chaque utilisateur, soit être copiés d'un utilisateur à un autre. Les deux occupent 2x/3x/4x l'espace (selon le nombre de doublons existants).
L'image de tout utilisateur est stockée dans son répertoire personnel. Plus précisément, ils sont stockés dans le répertoire ~/.local/share/containers/storage/
Une fois que toutes les conditions préalables sont remplies, vous pouvez exécuter la commande podman run à partir du shell d'un non-utilisateur et démarrer un conteneur.
Puisque j'utilise Caddy Server pour mon SSL, je l'utiliserai dans ce tutoriel. Pour exécuter Caddy Server en tant que conteneur sans racine à l'aide de Podman, tout en liant des ports inférieurs à 1024, je vais simplement exécuter la commande suivante :
$ whoami
utlisateur1
$ podman run -d --name=utlisateur1s-caddy -p 80:80 -p 443:443 caddy:alpine
e6ed67eb90e6d0f3475d78b287af941bc873f6d62db60d5c13b1106af80dc5ff
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e6ed67eb90e6 docker.io/library/caddy:alpine caddy run --confi... 2 seconds ago Up 2 seconds ago 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp utlisateur1s-caddy
$ ps aux | grep caddy
utlisateur1 3022 0.0 0.0 85672 2140 ? Ssl 06:53 0:00 /usr/bin/conmon --api-version 1 -c e6ed67eb90e6d0f3475d78b287af941bc873f6d62db60d5c13b1106af80dc5ff [...]
utlisateur1 3025 0.1 0.3 753060 32320 ? Ssl 06:53 0:00 caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
Comme vous pouvez le voir, l'utilisateur utlisateur1 n'est pas root et aussi que je n'ai pas utilisé la commande sudo pour élever les privilèges de l'utilisateur utlisateur1. J'ai pu exécuter le conteneur Caddy Server avec des privilèges sans racine à l'aide de Podman.
La sortie de la commande ps montre que le PID 3022 est celui d'un processus appartenant à l'utilisateur utlisateur1. Ce processus est le conteneur Caddy Server (j'ai coupé la sortie). Le PID 3025est un processus enfant du PID 3022 qui est également sous l'utilisateur utlisateur1.